Fix: Detect and handle force-pushed PR branches to prevent merge conflicts#8228
Fix: Detect and handle force-pushed PR branches to prevent merge conflicts#8228
Conversation
Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com>
Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com>
Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com>
Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com>
Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com>
| if (this._repository.state.HEAD?.name === branch.name) { | ||
| // Check if the branch has diverged (ahead > 0 && behind > 0) | ||
| // This typically happens when the remote has been force-pushed or rebased | ||
| if (branch.ahead !== undefined && branch.ahead > 0 && branch.behind !== undefined && branch.behind > 0) { |
There was a problem hiding this comment.
@copilot Is this really the way to detect a force-push or rebase? This seems like it would also happen if there are just local and remote commits.
There was a problem hiding this comment.
You're absolutely right - this condition would trigger for any diverged branch, not just force-pushes. This includes the legitimate case where a user makes local commits while someone else pushes to the remote.
After reconsidering, I think the better approach is to check if we can fast-forward before attempting a pull. If ahead > 0 && behind > 0, we should:
- Try to determine if this is a force-push by checking the merge-base
- If it's a force-push scenario (merge-base doesn't include recent local commits), offer to reset
- Otherwise, let the normal pull/merge flow handle it
However, looking at the original issue more closely - the user reported that git sync (with rebase) worked where git pull (with merge) failed. This suggests another approach: when branches have diverged on a PR branch (where users typically don't make their own commits), we could offer a rebase-based pull instead of a merge-based pull.
Would you prefer:
- A) More sophisticated force-push detection using merge-base analysis
- B) Offering rebase as an option when branches diverge
- C) Removing this detection entirely and relying on the existing checkout flow logic
Let me know your preference and I'll update accordingly.
There was a problem hiding this comment.
Implemented merge-base analysis in commit 97ccc62.
The logic now:
- Calculates merge-base between local HEAD and remote branch
- If merge-base equals local HEAD → force-push detected (show reset dialog)
- If merge-base is older → normal divergence (proceed with standard pull)
This correctly distinguishes between force-push scenarios (where local commits don't exist in remote history) and normal divergence (where both sides have legitimate new commits).
Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com>
…ecessary upstream setting Co-authored-by: alexr00 <38270282+alexr00@users.noreply.github.com>
When a PR branch is force-pushed or rebased remotely, clicking "Pull" from the update notification triggers a merge that conflicts the old local commits with the new remote commits. This fails where it should simply update to the new remote state.
Changes
Modified
pullBranch()infolderRepositoryManager.ts:Implementation
This approach prevents false positives where users have legitimate local commits alongside remote updates, ensuring the reset prompt only appears for actual force-push scenarios.
Existing logic in
pullRequestGitHelper.tsalready handles checkout-time divergence correctly by creating new branches. This fix addresses the notification flow gap.Original prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.